package com.yml.mybatis.gererator.meta;

import com.yml.mybatis.gererator.constant.DbType;
import org.apache.commons.lang3.StringUtils;

import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 连接信息
 *
 * @author YML
 * @since 2023-07-20 09:38
 */
public class DataSourceInfo {
    private final String url;

    private final String username;

    private final String password;

    private Connection connection = null;

    private String dbName;

    private DbType dbType;

    private final AtomicInteger max = new AtomicInteger(0);

    public DataSourceInfo(String url, String username, String password) {
        this.url = url;
        this.username = username;
        this.password = password;
    }

    public Connection getConnection() throws SQLException {
        if (this.connection != null && !this.connection.isClosed()) {
            return this.connection;
        }
        synchronized (this){
            if (this.connection != null && !this.connection.isClosed()) {
                return this.connection;
            }
            this.initConnection();
            return this.connection;
        }
    }

    private void initConnection() throws SQLException {
        assert StringUtils.isNotBlank(this.url);
        assert StringUtils.isNotBlank(this.username);
        if (max.get() >= 30){
            throw new RuntimeException("数据库连接口过多，请稍后再试");
        }
        this.connection = DriverManager.getConnection(this.url, this.username, this.password);
        this.dbName = this.connection.getCatalog();
        DatabaseMetaData metaData = this.connection.getMetaData();
        String product = metaData.getDatabaseProductName();
        if (StringUtils.equals("MySQL",product)){
            this.dbType = DbType.MYSQL;
        }else if (StringUtils.contains(product,"SQL Server")){
            this.dbType = DbType.SQL_SERVER;
        }
        max.incrementAndGet();
    }

    public void close() throws SQLException {
        if (this.connection == null) {
            return;
        }
        synchronized (this){
            if (this.connection == null) {
                return;
            }
            if (!this.connection.isClosed()){
                this.connection.close();
            }
            this.connection = null;
        }
        max.decrementAndGet();
    }

//    private static class DataSourceConnectionInfo{
//        private Connection connection = null;
//        private String connectionName = null;
//        private boolean used = false;
//        private final Long time = System.currentTimeMillis();
//
//        public DataSourceConnectionInfo(Connection connection, String connectionName) {
//            this.connection = connection;
//            this.connectionName = connectionName;
//        }
//
//        public Connection getConnection() {
//            return connection;
//        }
//
//        public String getConnectionName() {
//            return connectionName;
//        }
//
//        public boolean isUsed() {
//            return used;
//        }
//
//        public void setUsed(boolean used) {
//            this.used = used;
//        }
//
//        public Long getTime() {
//            return time;
//        }
//    }


    public String getUrl() {
        return url;
    }

    public String getUsername() {
        return username;
    }

    public String getPassword() {
        return password;
    }

    public String getDbName() {
        return dbName;
    }

    public DbType getDbType() {
        return dbType;
    }
}
